package net.lucamasini.ricette.client.ingredienti;

import static net.lucamasini.ricette.client.ServiceBus.getEventbus;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.lucamasini.ricette.client.RicettarioRequestFactory;
import net.lucamasini.ricette.client.ServiceBus;
import net.lucamasini.ricette.client.ingredienti.event.NewListaIngredientiEvent;
import net.lucamasini.ricette.client.ingredienti.event.RefreshListaIngredientiEvent;
import net.lucamasini.ricette.client.tipoingredienti.TipoIngredienteProxy;
import net.lucamasini.ricette.client.tipoingredienti.event.NewListaTipoIngredientiEvent;
import net.lucamasini.ricette.client.tipoingredienti.event.RefreshListaTipoIngredientiEvent;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.requestfactory.shared.Receiver;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;

public class Ingredienti extends Composite implements NewListaIngredientiEvent.Handler, NewListaTipoIngredientiEvent.Handler {
	
	private final static RicettarioRequestFactory requestFactory = GWT.create(RicettarioRequestFactory.class);

	private static IngredientiUiBinder uiBinder = GWT
			.create(IngredientiUiBinder.class);

	interface IngredientiUiBinder extends UiBinder<Widget, Ingredienti> {
	}

	@UiField CellTable<IngredienteProxy> ingredientiCellTable;
	@UiField SimplePanel pagerContainer;
	
	@UiField Button crea;
	@UiField Button modifica;
	@UiField Button cancella;

	private IngredientiDialog dialog;

	private final SingleSelectionModel<IngredienteProxy> selectionModel = new SingleSelectionModel<IngredienteProxy>();
	Map<String, TipoIngredienteProxy> cachedTipoIngrediente;
	private ListDataProvider<IngredienteProxy> ingredientiDataProvider = new ListDataProvider<IngredienteProxy>();
	
	public Ingredienti() {
		initWidget(uiBinder.createAndBindUi(this));

		requestFactory.initialize(ServiceBus.getEventbus());
		ingredientiDataProvider.addDataDisplay(ingredientiCellTable);
		
	    SimplePager pager = new SimplePager();
	    //pager.setPageSize(5);
	    ingredientiCellTable.setPageSize(10);
	    pager.setDisplay(ingredientiCellTable);
	    pagerContainer.setWidget(pager);
		
		ingredientiCellTable.addColumn(new TextColumn<IngredienteProxy>() {

			@Override
			public String getValue(IngredienteProxy object) {
				return object.getDescrizione();
			}
		}, "DESCRIZIONE");
		
		ingredientiCellTable.addColumn(new TextColumn<IngredienteProxy>() {

			@Override
			public String getValue(IngredienteProxy object) {
				return object.getKeyTipoIngrediente()!=null&&cachedTipoIngrediente.containsKey(object.getKeyTipoIngrediente())?cachedTipoIngrediente.get(object.getKeyTipoIngrediente()).getDescrizione():"ND";
			}
		}, "TIPO");

		ingredientiCellTable.addColumn(new TextColumn<IngredienteProxy>() {

			@Override
			public String getValue(IngredienteProxy object) {
				return object.getCalorie()!=null?object.getCalorie().toString():"ND";
			}
		}, "CALORIE");

		ingredientiCellTable.addColumn(new TextColumn<IngredienteProxy>() {

			@Override
			public String getValue(IngredienteProxy object) {
				return object.getGlutine()?"SI":"NO";
			}
		}, "GLUTINE");

		ingredientiCellTable.setSelectionModel(selectionModel);
		selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler(){

			@Override
			public void onSelectionChange(SelectionChangeEvent event) {
				if( selectionModel.getSelectedObject()!=null) {
					selectedButton(true);
				} else {
					selectedButton(false);
				}
			}
			
		});

		getEventbus().addHandler(NewListaIngredientiEvent.TYPE, this);
		getEventbus().addHandler(NewListaTipoIngredientiEvent.TYPE, this);

		getEventbus().fireEvent(new RefreshListaTipoIngredientiEvent(false));
	}

	@Override
	public void onNewListaIngredientiResponse(NewListaIngredientiEvent event) {

		// se ancora non e' arrivata la risposta all'evento del TipoIngrediente allora aspettiamo
		// tanto poi anche gli ingredienti vengono aggiornati !!
		if( cachedTipoIngrediente==null ) {
			return;
		}
		
		final List<IngredienteProxy> result = event.getListaIngredienti();

		ingredientiDataProvider.setList(result);
		if( selectionModel.getSelectedObject()!=null) {
			selectionModel.setSelected(selectionModel.getSelectedObject(), false);
		}
	}
	
	@Override
	public void onNewListaTipoIngredientiRequest(NewListaTipoIngredientiEvent event) {
		
		List<TipoIngredienteProxy> result = event.getListaTipoIngredienti();
		
		cachedTipoIngrediente = new HashMap<String, TipoIngredienteProxy>();
		for(TipoIngredienteProxy ti: result) {
			cachedTipoIngrediente.put(ti.getId(), ti);
		}
		
		dialog = new IngredientiDialog(Ingredienti.this);
		
		refreshIngredienti();
	}
	
	void refreshIngredienti() {
		getEventbus().fireEvent(new RefreshListaIngredientiEvent(true));
	}
	
	@UiHandler("crea")
	void onCreaIngrediente(ClickEvent event){
		dialog.creaIngrediente();
	}
	
	@UiHandler("modifica")
	void onModificaIngrediente(ClickEvent event){
		final IngredienteProxy ingrediente = selectionModel.getSelectedObject();

		dialog.modificaIngrediente(ingrediente);		
	}
	
	@UiHandler("cancella")
	void onCancellaIngrediente(ClickEvent event){
		final IngredienteProxy ingrediente = selectionModel.getSelectedObject();

		requestFactory.ingredientiRequest().cancellaIngrediente(ingrediente).fire(new Receiver<Void>() {

			@Override
			public void onSuccess(Void response) {
				refreshIngredienti();
			}
			
		});
	}
	
	@UiHandler("ricarica")
	void onRicaricaIngrediente(ClickEvent event){
		refreshIngredienti();
	}

	private void selectedButton(boolean selected) {
		modifica.setEnabled(selected);
		cancella.setEnabled(selected);
	}
}
